using System;
using System.Collections.Generic;
using System.Text;
using System.Data.Common;
using System.Data;
using System.Data.OleDb;
using Logging;

namespace AAM.SQL
{
    public class Command
    {

        private static Logger LOGGER = Logger.GetLogger("AAM.SQL.Command");

        private DbCommand command;

        public Command(DbCommand command) { this.command = command; }

        public string CommandText
        {
            get { return command.CommandText; }
            set { command.CommandText = value; }
        }

        public object this[string name]
        {
            get { return GetParameter(name); }
            set { SetParameter(name, value); }
        }

        public DbParameter AddParameter(DbType type, string name, object value)
        {
            DbParameter parameter = command.CreateParameter();
            parameter.DbType = type;
            if (parameter is OleDbParameter)
            {
                if (type.Equals(DbType.DateTime))
                {
                    parameter.DbType = DbType.String;
                    string newValue = ((DateTime)value).ToString("dd/MM/yyyy HH:mm:ss").Replace('.','/');
                    value = newValue;
                }
            }
            parameter.ParameterName = name;
            if (value == null) parameter.Value = DBNull.Value;
            else parameter.Value = value;
            command.Parameters.Add(parameter);
            return parameter;
        }

        public DbParameter AddParameter(string name, object value)
        {
            DbType type = DbType.Binary;
            if (value == null) type = DbType.String;
            else if (value is bool) type = DbType.Boolean;
            else if (value is int) type = DbType.Int32;
            else if (value is string) type = DbType.String;
            else if (value is DateTime) type = DbType.DateTime;
            else if (value is double) type = DbType.Double;
            else throw new Exception();
            return AddParameter(type, name, value);
        }

        public DbParameter AddParameter(object value)
        {
            return AddParameter("@Param" + command.Parameters.Count.ToString(), value);
        }

        public DbParameter AddParameter(DbType type, string name)
        {
            DbParameter parameter = command.CreateParameter();
            parameter.DbType = type;
            parameter.ParameterName = name;
            command.Parameters.Add(parameter);
            return parameter;
        }

        public void SetParameter(string name, object value)
        {
            if (value == null) command.Parameters[name].Value = DBNull.Value;
            else command.Parameters[name].Value = value;
        }

        public object GetParameter(string name)
        {
            object value = command.Parameters[name].Value;
            if (value == DBNull.Value) return null;
            return value;
        }

        public void ClearParameters()
        {
            command.Parameters.Clear();
        }

        public void InitParameters()
        {
            foreach (DbParameter parameter in command.Parameters)
            {
                parameter.Value = null;
            }
        }


        public DataReader ExecuteReader()
        {
            try
            {
                return new DataReader(command.ExecuteReader());
            }
            catch (Exception exc)
            {
                LOGGER.Throwing("AAM.SQL.Command", "ExecuteReader", exc);
                throw exc;
            }
        }
        public int ExecuteNonQuery() { 
            try
            {
                return command.ExecuteNonQuery(); 
            }
            catch (Exception exc)
            {
                LOGGER.Throwing("AAM.SQL.Command", "ExecuteNonQuery", exc);
                throw exc;
            }
        }
        public void Dispose() { command.Dispose(); }

        public object ExecuteScalar() { 
            try
            {
                object obj = command.ExecuteScalar(); 
                if(DBNull.Value.Equals(obj)) return null; 
                return obj;
            }
            catch (Exception exc)
            {
                LOGGER.Throwing("AAM.SQL.Command", "ExecuteScalar", exc);
                throw exc;
            }
    }
    }
}
